package org.example.design.exerciseold.dependencyinvert;

/**
 * @Auther: lingshi
 * @Date: 2020/5/8 10:13
 * @Description: 依赖倒置原则：高层不能依赖于低层、二者都应该依赖于抽象接口
 *  如v1 面向实现编程 高层依赖于低层，代码耦合性很高不便于维护和扩展
 *  v2  提取一个公用的接口(StudyService )不同的学习不同的实现类、调用方通过构造器注入不同的实现类对象最终返回它的学习方法
 *   但这种方法容易造成对象的创建开销
 *  v3 在调用方创建一个公用set方法并定义一个私有的studyService,根据set进来的实现类对象构建不同的对象
 */
public class TomStudyTest {
    public static void main(String[] args) {
        /** v1
         * 面向实现编程：
         * 如以下示例三个学习方法需要调用三个方法、假设现在要新增多个学习方法
         * 那就需要我们在实现类创建方法、并且在调用处进行调用
         * 缺点：代码冗余性、可扩展性、维护性都大大的增加
         */
//        Tom to = new Tom();
//        to.studyJava();
//        to.studyAi();
//        to.studyPython();

        /**v2
         * 使用这种方式对对象的创建开销就很大了，
         */
//        Tom to= new Tom(new AIStudyServiceImpl());
//        Tom to1= new Tom(new JavaStudyServiceImpl());
//        Tom to2= new Tom(new PythonStudyServiceImpl());


        /**v3
         * 定义一个公共set方法根据set进去的不同值来调用不同的实现类学习方法
         */
        Tom to = new Tom();
        to.setStudyTomImpl(new JavaStudyServiceImpl());
        to.TomStudy();

        Tom to1 = new Tom();
        to1.setStudyTomImpl(new JavaStudyServiceImpl());
        to1.TomStudy();

        System.out.println("tom "+to);
        System.out.println("tom1 "+to1);
        System.out.println("tom hashCode"+to.hashCode());
        System.out.println("tom1 hashCode"+to1.hashCode());


    }


}
